package org.darcy.service.summary;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.darcy.dao.CheckDeliveryMapper;
import org.darcy.dao.business.BusinessContractMapper;
import org.darcy.dao.business.BusinessFinancialReceivedMapper;
import org.darcy.entity.CheckDelivery;
import org.darcy.entity.business.BusinessContract;
import org.darcy.entity.business.BusinessFinancialReceived;
import org.darcy.vo.ContractAmount;
import org.darcy.vo.project.CapitalItem;
import org.darcy.vo.project.CapitalSummary;
import org.darcy.vo.project.HomeSummary;
import org.darcy.vo.project.PieItem;
import org.darcy.vo.project.ProjectSummary;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.hutool.json.JSONUtil;

/**
 * 项目统计和财务统计 服务实现
 */
@Service
public class SummaryService {

	@Autowired
	private BusinessContractMapper mapper;

	@Autowired
	private CheckDeliveryMapper CheckDeliveryMapper;

	@Autowired
	private BusinessFinancialReceivedMapper BusinessFinancialReceivedMapper;

	/**
	 * 获取首页统计数据
	 * 
	 */
	public HomeSummary homeSummary(HomeSummary param) {
		HomeSummary data = new HomeSummary();
		Set<String> typeSet = new HashSet<String>();

		List<CheckDelivery> deliveryList = CheckDeliveryMapper.getHomeSummary(param);
		// 新签订合同额列表
		float[] monthDataNewContract = new float[12];
		// 完成服务额列表
		float[] monthDataFinishedContract = new float[12];
		for (CheckDelivery a : deliveryList) {
			typeSet.add(a.getItemName());
			// 按月统计
			int month = a.getContractBegin().getMonth();
			if (a.getArchiveNo() == null) {
				monthDataNewContract[month] += a.getItemCapital();
			} else {
				monthDataFinishedContract[month] += a.getItemCapital();
			}
		}
		data.setMonthDataNewContract(monthDataNewContract);
		data.setMonthDataFinishedContract(monthDataFinishedContract);

		// 到款列表
		List<BusinessFinancialReceived> receivedList = BusinessFinancialReceivedMapper.getHomeSummary(param);
		float[] monthDataReceived = new float[12];
		for (BusinessFinancialReceived a : receivedList) {
			// 按月统计
			int month = a.getPayTime().getMonth();
			monthDataReceived[month] += a.getPayAmount();
		}
		data.setMonthDataReceived(monthDataReceived);

		// 明细数据初始化
		Map<String, Float> map1 = new HashMap<String, Float>();// key=业务类型，value=业务类型对应的完成服务额
		Map<String, Float> map2 = new HashMap<String, Float>();// key=业务类型，value=业务类型对应的应收款
		Map<String, Float> map3 = new HashMap<String, Float>();// key=业务类型，value=业务类型对应的收款
		for (String a : typeSet) {
			map1.put(a, 0f);
			map2.put(a, 0f);
			map3.put(a, 0f);
		}
		// 1.完成服务额
		for (CheckDelivery a : deliveryList) {
			for (String type : typeSet) {
				if (a.getItemName().equals(type)) {
					map1.put(type, map1.get(type) + a.getItemCapital());
				}
			}
		}
		// 3.收款
		for (BusinessFinancialReceived a : receivedList) {
			/// 处理收款金额
			List<ContractAmount> list = JSONUtil.parseArray(a.getPayDetail()).toList(ContractAmount.class);
			for (ContractAmount b : list) {
				float value = b.getValue() == null ? 0f : b.getValue();
				float oldValue = map3.get(b.getName()) == null ? 0f : map3.get(b.getName());
				map3.put(b.getName(), oldValue + value);
			}
		}
		// 2.应收款
		for (String type : typeSet) {
			map2.put(type, map1.get(type) - map3.get(type));
		}

		// 完成服务额明细
		List<PieItem> contractList = new ArrayList<PieItem>();
		// 应收款明细
		List<PieItem> notReceivedList = new ArrayList<PieItem>();
		for (String key : typeSet) {
			contractList.add(new PieItem(key, map1.get(key)));
			notReceivedList.add(new PieItem(key, map2.get(key)));
		}
		data.setContractList(contractList);
		data.setNotReceivedList(notReceivedList);

		return data;
	}

	/**
	 * 获取项目统计数据
	 * 
	 */
	public ProjectSummary projectSummary(ProjectSummary param) {
		ProjectSummary data = new ProjectSummary();
		List<BusinessContract> list1 = mapper.count1(param);
		List<BusinessContract> list2 = mapper.count2(param);
		List<BusinessContract> list3 = mapper.count3(param);
		data.setCount1(list1.size());
		data.setCount2(list2.size());
		data.setCount3(list3.size());
		data.setCount4(mapper.count4(param));

		// 明细数据处理
		Map<String, Integer> map1 = new HashMap<String, Integer>();// key=业务类型，value=业务类型对应的进行中项目数
		Map<String, Integer> map2 = new HashMap<String, Integer>();// key=业务类型，value=业务类型对应的新项目数
		Map<String, Integer> map3 = new HashMap<String, Integer>();// key=业务类型，value=业务类型对应的完成项目数
		List<String> xAxis = new ArrayList<String>();
		int[] monthData1 = new int[12];
		int[] monthData2 = new int[12];

		Set<String> typeSet = new HashSet<String>();
		for (BusinessContract a : list1) {
			typeSet.addAll(Arrays.asList(a.getProjectType().split(",")));
		}
		for (BusinessContract a : list2) {
			typeSet.addAll(Arrays.asList(a.getProjectType().split(",")));
		}
		for (BusinessContract a : list3) {
			typeSet.addAll(Arrays.asList(a.getProjectType().split(",")));
		}
		for (String a : typeSet) {
			xAxis.add(a);
			map1.put(a, 0);
			map2.put(a, 0);
			map3.put(a, 0);
		}

		for (BusinessContract a : list1) {
			for (String type : typeSet) {
				if (a.getProjectType().contains(type)) {
					int count = map1.get(type);
					count++;
					map1.put(type, count);
				}
			}
		}

		for (BusinessContract a : list2) {
			// 按月统计
			int month = a.getContractBegin().getMonth();
			monthData1[month]++;
			for (String type : typeSet) {
				if (a.getProjectType().contains(type)) {
					int count = map2.get(type);
					count++;
					map2.put(type, count);
				}
			}

		}

		for (BusinessContract a : list3) {
			// 按月统计
			int month = a.getContractBegin().getMonth();
			monthData2[month]++;
			// 按业务类别统计
			for (String type : typeSet) {
				if (a.getProjectType().contains(type)) {
					int count = map3.get(type);
					count++;
					map3.put(type, count);
				}
			}
		}

		// 数据组装
		data.setXAxis(xAxis);
		List<Integer> seriesData1 = new ArrayList<Integer>();
		List<Integer> seriesData2 = new ArrayList<Integer>();
		List<Integer> seriesData3 = new ArrayList<Integer>();
		for (String key : xAxis) {
			seriesData1.add(map1.get(key));
			seriesData2.add(map2.get(key));
			seriesData3.add(map3.get(key));
		}
		data.setSeriesData1(seriesData1);
		data.setSeriesData2(seriesData2);
		data.setSeriesData3(seriesData3);
		data.setMonthData1(monthData1);
		data.setMonthData2(monthData2);
		return data;
	}

	/**
	 * 获取财务统计数据
	 * 
	 */
	public CapitalSummary capitalSummary(CapitalSummary param) {
		CapitalSummary data = new CapitalSummary();
		List<CapitalItem> list = CheckDeliveryMapper.getCapitalSummary(param);
		// 列名称
		Set<String> columnSet = list.stream().map(a -> a.getItemName()).collect(Collectors.toSet());
		data.setColumnList(columnSet.stream().collect(Collectors.toList()));

		if (param.getQueryType() == 1) {
			// 按用户分组
			Map<String, List<CapitalItem>> map = list.stream().collect(Collectors.groupingBy(CapitalItem::getUserName));
			// 初始化左侧用户列
			data.getUserList().addAll(map.keySet());
			// 初始化数据
			float[][] dataList = new float[map.keySet().size()][data.getColumnList().size()];
			int i = 0, j = 0;
			for (String key : map.keySet()) {
				float[] row = dataList[i];
				List<CapitalItem> tmp = map.get(key);
				for (CapitalItem a : tmp) {
					j = 0;
					for (String column : data.getColumnList()) {
						if (a.getItemName().equals(column) && a.getItemCapital() > 0) {
							row[j] = a.getItemCapital();
						}
						j++;
					}
				}
				dataList[i] = row;
				i++;
			}
			data.setDataList(dataList);
		}
		if (param.getQueryType() == 2) {
			// 按部门分组
			Map<String, List<CapitalItem>> map = list.stream().collect(Collectors.groupingBy(CapitalItem::getDeptName));
			// 初始化左侧部门列
			data.getDeptList().addAll(map.keySet());
			// 初始化数据
			float[][] dataList = new float[map.keySet().size()][data.getColumnList().size()];
			int i = 0, j = 0;
			for (String key : map.keySet()) {
				float[] row = dataList[i];
				List<CapitalItem> tmp = map.get(key);
				for (CapitalItem a : tmp) {
					j = 0;
					for (String column : data.getColumnList()) {
						if (a.getItemName().equals(column) && a.getItemCapital() > 0) {
							row[j] = a.getItemCapital();
						}
						j++;
					}
				}
				dataList[i] = row;
				i++;
			}
			data.setDataList(dataList);
		}

		return data;

	}

}
